package main

import "fmt"

func main() {

	a := []int{1, 2, 3, 4}
	fmt.Printf(" a : %v  len : %d  cap : %d \n", a, len(a), cap(a))

	a = appendInt(a, 5)
	fmt.Printf(" a : %v  len : %d  cap : %d \n", a, len(a), cap(a))

	a = appendInt(a, 6)
	fmt.Printf(" a : %v  len : %d  cap : %d \n", a, len(a), cap(a))

	fmt.Println()

	var x, y []int
	for i := 0; i < 10; i++ {
		y = appendInt(x, i)
		fmt.Printf("%d cap=%d\t%v\n", i, cap(y), y)
		x = y
	}

}

func appendInt(origin []int, x int) []int {

	// 初始化一个新的数组
	var zInt []int

	// 原始的数组长度
	zlen := len(origin) + 1

	// 如果原始数组的长度，小于 原始数组的 容量。说明可以继续添加数据
	// 如果原始数组的长度，大于 原始数组的 容量，需要扩容才可以添加数据
	if zlen < cap(origin) {
		zInt = origin[:zlen]
	} else {
		// 新数组的容量，等于原始数组的长度
		zCap := zlen
		// 如果新数组的容量，小于 原始数组长度的2倍。
		// 那么就，将新数组的容量 扩容到 原始数组长度的2倍
		if zCap < 2*len(origin) {
			zCap = 2 * len(origin)
		}
		// 生成新的数组，长度是原始数组的长度，容量是原始数组长度的2倍速
		zInt = make([]int, zlen, zCap)
		// 拷贝原始数组的数据，到新的数组中
		copy(zInt, origin)
	}

	// 将新的数值添加到 新数组的最后一位
	zInt[len(origin)] = x
	return zInt

}
